//
//  AdsViewController.swift
//  Automobile
//
//  Created by erkebulan elzhan on 7/27/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.
//

import UIKit
import SnapKit

protocol AdCreatorProtocol: class {
    func getImagesData (images: [UIImage]?)
    func getDescriptions (text: String?, onlyAutoNomad: Bool)
    func getPhoneNumber (number: NumberViewModel.Number?, onlyChat: Bool, noReseller: Bool, isProtected: Bool)
    func getContacts (name: String?, email: String?, city: City?)
    func getPrice (price: Int?, isObmen: Bool, isRastomozhen: Bool)
    
    func giveStateNumber() -> String
    func removeEverything()
    func showAdPreview ()
}



final class AdsViewController: UIViewController, Alertable {
    
    // MARK: - Outlets
    
    lazy private var adHeaderView: AdHeaderView = {
        let adHV = AdHeaderView()
        adHV.delegate = self
        return adHV
    }()
    
    lazy private var adEmptyView: AdEmptyView = {
        let adEV = AdEmptyView()
        adEV.delegate = self
        return adEV
    }()
    
    lazy private var adsTableView: UITableView = {
        let table = UITableView()
        table.delegate = self
        table.dataSource = self
        table.backgroundColor = .whiteBlueColor
        table.tableFooterView = UIView()
        table.register(AdCell.self, forCellReuseIdentifier: "myAdCell")
        table.addSubview(refreshingControl)
        return table
    }()
    
    private var overlayView: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.7)
        return view
    }()
    
    private lazy var spinnerView = SpinnerView()
    
    private lazy var refreshingControl : RefreshView = {
        let refControl = RefreshView()
        refControl.tintColor = .blueColor
        return refControl
    }()

    private var menuPopup: MenuPopup!
    
    // MARK: - Properties
    
    private lazy var adHomeModel: AdsHomeModel = {
        let ahm = AdsHomeModel()
        ahm.delegate = self
        return ahm
    }()

    // MARK: - UI Actions

    @objc private func showMenuPopup (sender: UIButton) {
        let indexPath = IndexPath(row: sender.tag, section: 0)
        menuPopup = MenuPopup(size: CGSize(width: 214, height: 200))
        menuPopup.addButtons(buttons: adHomeModel.menuItems)
        self.showPopup(for: indexPath)
        self.subscribeToPopup()
    }
    
    @objc private func overlayDidClick (sender: UITapGestureRecognizer) {
        if (!adHomeModel.isMenuHidden) {
            self.hidePopup()
        }
    }
    
    @objc func doRefresh () {
        refreshingControl.endRefreshing()
        adHomeModel.getMyAds()
    }
    
    @objc private func updateSinglePost (notification: NSNotification) {
        if let userInfo = notification.userInfo {
            if let post = userInfo["post"] as? Post, let index = userInfo["index"] as? Int {
                self.adHomeModel.currentAds[index] = post
                adsTableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .middle)
            }
        }
    }
    
    // MARK: - Init
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white
        self.setUpNav()
        self.setUpUI()
        adHomeModel.getMyAds()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.navigationController?.navigationBar.isHidden = true
        
    }
    
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        if !adHomeModel.isMenuHidden, let indexPath = adHomeModel.menuIndexPath {
            self.showPopup(for: indexPath)
        }
    }
}


// MARK: - Methods

extension AdsViewController: ViewModelProtocol {
    
    func updateSpinner(showSpinner: Bool) {
        view.isUserInteractionEnabled = !showSpinner
        showSpinner ? spinnerView.startAnimating() : spinnerView.stopAnimating()
    }
    
    func didHappenError(error: RequestError) {
        self.alertError(error: error)
    }
    
    func updatePosts() {
        
        if !view.subviews.contains(adsTableView) {
            self.showAdsTableView()
        }
        
        adsTableView.reloadData()
    }
    
    func updateCities(cities: [City]?) {}
}


// MARK: - Ads Table View

extension AdsViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let carVC = MyAdViewController()
        carVC.post = adHomeModel.currentAds[indexPath.row]
        carVC.comeFromCellWithIndex = indexPath.row
        self.navigationController?.pushViewController(carVC, animated: true)
        NotificationCenter.default.addObserver(self, selector: #selector(updateSinglePost(notification:)), name: NSNotification.Name(rawValue: "adHomeUpdate"), object: nil)
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return adHomeModel.currentAds.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "myAdCell") as! AdCell
        cell.adCellModel = AdCellModel(post: adHomeModel.currentAds[indexPath.row])
        
        cell.menuBtn.tag = indexPath.row
        cell.menuBtn.addTarget(self, action: #selector(showMenuPopup(sender:)), for: .touchUpInside)
        return cell
    }
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        let offsetY = scrollView.contentOffset.y
        let contentHeight = scrollView.contentSize.height
        
        if offsetY > contentHeight - scrollView.frame.size.height {
            if adHomeModel.nextPage != nil {
                adHomeModel.getMyAds(paginate: true)
            }
        }
    }
}

// MARK: - UI

// Base

extension AdsViewController {
    
    private func setUpUI () {
        self.view.addSubview(adHeaderView)
        self.view.addSubview(spinnerView)
        self.overlayView.isHidden = true
        
        let overlayGesture = UITapGestureRecognizer(target: self, action: #selector(overlayDidClick(sender:)))
        self.overlayView.addGestureRecognizer(overlayGesture)
        
        if (adHomeModel.currentAds.count == 0) {
            self.showNoAdView()
        } else {
            self.showAdsTableView()
        }
        
        self.view.addSubview(overlayView)
        
        refreshingControl.addTarget(self, action: #selector(doRefresh), for: .valueChanged)
        
        adHeaderView.snp.makeConstraints { (make) in
            make.top.equalTo(view.safeAreaLayoutGuide).offset(16)
            make.height.equalTo(76)
            make.leading.trailing.equalToSuperview()
        }
        
        overlayView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        
        spinnerView.snp.makeConstraints { (make) in
            make.center.equalToSuperview()
        }
    }
    
    private func setUpNav () {
        self.navigationController?.navigationBar.isHidden = true
    }
    
    // MARK: - No Ad / Ad Mode Switching
    
    private func showNoAdView () {
        self.view.addSubview(adEmptyView)
        adEmptyView.snp.makeConstraints { (make) in
            make.left.trailing.equalToSuperview()
            make.bottom.equalTo(view.safeAreaLayoutGuide)
            make.top.equalTo(adHeaderView.snp.bottom)
        }
        self.view.bringSubviewToFront(overlayView)
        self.view.bringSubviewToFront(spinnerView)
    }
    
    private func showAdsTableView () {
        self.view.addSubview(adsTableView)
        adsTableView.snp.makeConstraints { (make) in
            make.left.trailing.equalToSuperview()
            make.bottom.equalTo(view.safeAreaLayoutGuide)
            make.top.equalTo(adHeaderView.snp.bottom)
        }
        self.view.bringSubviewToFront(overlayView)
        self.view.bringSubviewToFront(spinnerView)
    }
    

    private func showSelectCarView () {
        let selectCarVC = SelectCarViewController()
        self.navigationController?.pushViewController(selectCarVC, animated: true)
    }
}


// Header And Empty View Delegates

extension AdsViewController: AdEmptyViewDelegate, AdHeaderViewDelegate {
    
    // Show Select Car Modal
    
    func onCreateAdClick() {
        self.showSelectCarView()
    }
    
    func headerButtonPressed() {
        self.showSelectCarView()
    }
    
    private func showPopup (for indexPath: IndexPath) {
        if let cell = adsTableView.cellForRow(at: indexPath) {
            adHomeModel.menuIndexPath = indexPath
            adHomeModel.isMenuHidden = false
            self.overlayView.isHidden = false
            adsTableView.isUserInteractionEnabled = false
            
            let point = adsTableView.convert(CGPoint(x: self.view.bounds.width - 225, y: cell.frame.maxY), to: self.view)
            let yPosition = point.y - 16 + 150 > view.frame.height ? point.y - 16 - 150 : point.y - 16
            
            let frame = CGRect(x: point.x,
                               y: yPosition,
                               width: 214, height: 200)
            menuPopup.frame = frame
            self.view.addSubview(menuPopup)
        }
    }
    
    private func hidePopup () {
        adHomeModel.menuIndexPath = nil
        adHomeModel.isMenuHidden = true
        self.overlayView.isHidden = true
        adsTableView.isUserInteractionEnabled = true
        menuPopup.removeFromSuperview()
        self.unsubscribeToPopup()
    }
    
    
    private func subscribeToPopup () {
        NotificationCenter.default.addObserver(self, selector: #selector(getMenuClickUpdate(notification:)), name: NSNotification.Name(rawValue: "menuClick"), object: nil)
    }
    private func unsubscribeToPopup () {
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "menuClick"), object: nil)
    }
}


// MARK: - Menu Popup

extension AdsViewController {
    
    private func editCell () {
        let editVC = EditViewController()
        editVC.post = self.adHomeModel.currentAds[adHomeModel.menuIndexPath.row]
        self.navigationController?.pushViewController(editVC, animated: true)
    }
    
    private func toTopCell () {}
    
    private func pauseAd () {
        adHomeModel.pauseAd(index: adHomeModel.menuIndexPath.row)
    }
    
    @objc private func getMenuClickUpdate (notification: NSNotification) {
        if let userInfo = notification.userInfo {
            if let menuItemIndex = userInfo["index"] as? Int {
                switch menuItemIndex {
                case 0:
                    self.editCell()
                case 1:
                    self.toTopCell()
                default:
                    self.pauseAd()
                }
            }
        }
    }
}
